package com.powernode.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.constant.BusinessEnum;
import com.powernode.domain.MemberAddr;
import com.powernode.domain.Order;
import com.powernode.domain.OrderItem;
import com.powernode.exception.BusinessException;
import com.powernode.feign.OrderMemberFeign;
import com.powernode.mapper.OrderItemMapper;
import com.powernode.mapper.OrderMapper;
import com.powernode.model.Result;
import com.powernode.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private OrderMemberFeign orderMemberFeign;

    /**
     * 多条件分页查询订单
     *
     * @param page
     * @param orderNumber
     * @param status
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public Page<Order> queryOrderPage(Page<Order> page, String orderNumber, Integer status, Date startTime, Date endTime) {

        // 多条件分页查询订单列表
        page = orderMapper.selectPage(page, new LambdaQueryWrapper<Order>()
                .eq(ObjectUtil.isNotNull(status), Order::getStatus, status)
                .between(ObjectUtil.isAllNotEmpty(startTime, endTime), Order::getCreateTime, startTime, endTime)
                .eq(StringUtils.hasText(orderNumber), Order::getOrderNumber, orderNumber)
                .orderByDesc(Order::getCreateTime)
        );
        // 从订单分页对象中获取订单记录
        List<Order> orderList = page.getRecords();
        // 判断是否有值
        if (CollectionUtils.isEmpty(orderList) || orderList.size() == 0) {
            return page;
        }
        // 从订单记录集合中获取订单编号集合
        List<String> orderNumberList = orderList.stream().map(Order::getOrderNumber).collect(Collectors.toList());
        // 根据订单编号查询所有订单商品条目对象集合
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                .in(OrderItem::getOrderNumber, orderNumberList)
        );
        // 循环遍历订单记录集合
        orderList.forEach(order -> {
            // 从订单商品条目对象集合中过滤出与当前订单记录的编号一致的商品条目对象集合
            List<OrderItem> itemList = orderItemList.stream().filter(orderItem -> orderItem.getOrderNumber().equals(order.getOrderNumber())).collect(Collectors.toList());
            order.setOrderItems(itemList);
        });
        // 返回对应的分页数据
        return page;
    }

    /**
     * 根据订单编号查询订单的详情
     * @param orderNumber
     * @return Order 订单数据
     */
    @Override
    public Order queryOrderDetailByOrderNumber(Long orderNumber) {
        // 根据订单的编号 查询订单的信息
        Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, orderNumber));
        // 根据订单的编号 查询订单 商品 条目 对象集合
        List<OrderItem> orderItems = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderNumber, orderNumber));
        // 组装数据
        order.setOrderItems(orderItems);
        // 获取收获地址标识 然后查询地址的详情信息 远程调用
        Result<MemberAddr> addrById = orderMemberFeign.getMemberAddrById(order.getAddrOrderId());
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(addrById.getCode())) {
            // 操作失败
            throw new BusinessException(addrById.getMsg());
        }
        // 赋值对应的数据
        if (CollectionUtil.isNotEmpty((Collection<?>) addrById.getData())) {
            // 赋值数据
            order.setUserAddrOrder(addrById.getData());
        }
        // 远程根据会员的openid 获取会员的昵称
        Result<String> nickNameByOpenId = orderMemberFeign.getNickNameByOpenId(order.getOpenId());
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(nickNameByOpenId.getCode())) {
            // 操作失败
            throw new BusinessException(nickNameByOpenId.getMsg());
        }
        // 赋值对应的数据 昵称
        order.setNickName(nickNameByOpenId.getData());
        // 返回订单数据
        return order;
    }
}